'''
Created on 2010-6-25

@author: Zizon
'''
from com.google.code.zkit.twitter.ProxyHandler import ProxyHandler
from google.appengine.api.urlfetch import fetch , POST
from com.google.code.zkit.twitter.oauth.AuthorizePageProcessor import AuthorizePageProcessor
from com.google.code.zkit.twitter.oauth.PinPageProcessor import PinPageProcessor
from com.google.code.zkit.twitter.oauth.OauthHeaderBuilder import OauthHeaderBuilder
from com.google.code.zkit.twitter.oauth.UserIdentify import UserIdentify
import logging
import hashlib
import base64
from com.google.code.zkit.twitter.oauth.Config import MemcacheConfig

# a hack for compatible purpose , 
# as twitter drop this api when swtich to oauth
class VerifyCredentialsProxy(ProxyHandler):
    
    def get(self, *args):
        self.authorize()
    
    def post(self, *args):
        self.authorize()
        
    def authorize(self):
        # prepare user name and password
        basic_authorize_info = base64.b64decode(self.request.headers["Authorization"].replace("Basic", "").replace("relm", "").replace(" " , ""))
        pair = basic_authorize_info.split(":")
        name = pair[0]
        password = pair[1]
        
        # analysis response format
        suffix = ""
        if "verify_credentials.xml" in self.request.path:
            suffix = "xml"
        elif "verify_credentials.json" in self.request.path:
            suffix = "json"

        # do authorize job
        response = type(self).doAuthorize(name, password, suffix)
        logging.debug("responds : %s , headers : %s" % (response.headers , response.content))
        
        # write response
        self.response.headers = response.headers
        self.response.out.write(response.content)
        
    
    # verfy credential return the same as /user/show.xx
    @classmethod
    def doAuthorize(self, name, password, suffix="json"):
        # get oauth_token and oauth_token_secret
        response = fetch(
                         "https://api.twitter.com/oauth/request_token",
                         method=POST,
                         headers=OauthHeaderBuilder.buildHeaderByVaryParameter(
                                                                                  "https://api.twitter.com/oauth/request_token",
                                                                                  "POST",
                                                                                  "",
                                                                                  oauth_callback="oob"
                                                                               )
                        )
        
        # save token parameters
        logging.debug("request_token response : %s , headers : %s" % (response.content, response.headers))
        token_parameters = self.convertParameters(response.content, False)
        
        # get the authorize page
        response = fetch(
                         "https://api.twitter.com/oauth/authorize?oauth_token=%s" % token_parameters["oauth_token"],
                          method=POST
                         )
        
        # retrieve authenticity_token in authorize page 
        logging.debug("authorize page headers %s" % response.headers)
        page = AuthorizePageProcessor()
        page.feed(response.content)
        authenticity_token = page.authenticity_token
        logging.debug("authenticity_token : %s" % authenticity_token) 
        
        # hack allow action in authorize page
        response = fetch(
                         "https://api.twitter.com/oauth/authorize?oauth_token=%s&oauth_token_secret=%s&oauth_callback_confirmed=true" % (token_parameters["oauth_token"], token_parameters["oauth_token_secret"]),
                         "session[username_or_email]=%s&session[password]=%s&authenticity_token=%s&oauth_token=%s" % (name, password, authenticity_token, token_parameters["oauth_token"]),
                         method=POST
                         )
        
        # retrieve pin_code
        logging.debug("authorize after hack page headers %s" % response.headers)
        page = PinPageProcessor()
        page.feed(response.content)
        pin_code = page.pin_code
        logging.debug("pin_code : %s" % pin_code)
        
        # get access token
        response = fetch(
                         "https://api.twitter.com/oauth/access_token",
                          method=POST,
                          headers=OauthHeaderBuilder.buildHeaderByVaryParameter(
                                                                                  "https://api.twitter.com/oauth/access_token",
                                                                                  "POST",
                                                                                  token_parameters["oauth_token_secret"],
                                                                                  oauth_verifier=pin_code,
                                                                                  oauth_token=token_parameters["oauth_token"]
                                                                                )
                        )
        logging.debug("access_token response : %s , headers : %s" % (response.content, response.headers))
        acces_token_info = self.convertParameters(response.content, False)
        
        # persist user infomations , note the acess token is named oauth_token_secret
        user = UserIdentify(
                            key_name=name,
                            oauth_token_secret=acces_token_info["oauth_token_secret"],
                            oauth_token=acces_token_info["oauth_token"],
                            password=hashlib.md5(password).hexdigest()
                            )
        if user.put() != None:
            self.client.set(name, user , namespace=MemcacheConfig.user_cache_namespace)
        
        # fetch user info te feed verify credential call    
        return fetch(
                          "http://api.twitter.com/1/users/show.%s?screen_name=%s" % (suffix, name),
                           method="GET",
                           headers=OauthHeaderBuilder.buildHeaderByVaryParameter(
                                                                                 "http://api.twitter.com/1/users/show.%s" % suffix ,
                                                                                 "GET",
                                                                                  acces_token_info["oauth_token_secret"],
                                                                                  screen_name=name,
                                                                                  oauth_token=acces_token_info["oauth_token"]
                                                                                )
                        )
       
        
